/*
 *  Copyright (C) 2005-2007 Renier Roth
 *  www.renier.de
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package de.renier.jkeepass;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;

import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import de.renier.jkeepass.actions.ActionManager;
import de.renier.jkeepass.components.ContainerElementTree;
import de.renier.jkeepass.elements.ContainerElement;
import de.renier.jkeepass.listener.ElementSelectionListener;
import de.renier.jkeepass.renderer.ElementTreeRenderer;

/**
 * ElementTreePanel
 *
 * @author <a href="mailto:software@renier.de">Renier Roth</a>
 */
public class ElementTreePanel extends JPanel {

  private static final long serialVersionUID = 1L;
  private JScrollPane jScrollPane = null;
  private JTree jTree = null;
  private JPopupMenu jPopupMenu = null;

  /**
   * This is the default constructor
   */
  public ElementTreePanel() {
    super();
    initialize();
  }

  /**
   * This method initializes this
   * 
   * @return void
   */
  private void initialize() {
    GridBagConstraints gridBagConstraints = new GridBagConstraints();
    gridBagConstraints.fill = GridBagConstraints.BOTH;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.weightx = 1.0;
    gridBagConstraints.weighty = 1.0;
    gridBagConstraints.gridx = 0;
    this.setSize(400, 400);
    this.setLayout(new GridBagLayout());
    this.setPreferredSize(new Dimension(400, 400));
    this.setMinimumSize(new Dimension(200, 400));
    this.add(getJScrollPane(), gridBagConstraints);
  }

  /**
   * This method initializes jScrollPane	
   * 	
   * @return javax.swing.JScrollPane	
   */
  private JScrollPane getJScrollPane() {
    if (jScrollPane == null) {
      jScrollPane = new JScrollPane();
      jScrollPane.setViewportView(getJTree());
    }
    return jScrollPane;
  }

  /**
   * This method initializes jTree	
   * 	
   * @return javax.swing.JTree	
   */
  private JTree getJTree() {
    if (jTree == null) {
      jTree = new ContainerElementTree();
      setDefaultTreeModel(new DefaultMutableTreeNode(new ContainerElement(Messages.getString("ElementTreePanel.0"),null))); //$NON-NLS-1$
      // set renderer
      jTree.setCellRenderer(new ElementTreeRenderer());
      jTree.addTreeSelectionListener(new ElementSelectionListener());
      jTree.addMouseListener(new ElementTreeMouseListener());
    }
    return jTree;
  }
  
  /**
   * setDefaultTreeModel
   * 
   * @param node
   */
  public void setDefaultTreeModel(DefaultMutableTreeNode node) {
    jTree.setModel(new DefaultTreeModel(node));
  }
  
  /**
   * getRootNode
   *
   * @return
   */
  public DefaultMutableTreeNode getRootNode() {
    return (DefaultMutableTreeNode) jTree.getModel().getRoot();
  }

  /**
   * treeNodeChanged
   *
   * @param node
   */
  public void treeNodeChanged(DefaultMutableTreeNode node) {
    ((DefaultTreeModel) jTree.getModel()).nodeChanged(node);
  }

  /**
   * treeNodeStructureChanged
   *
   * @param node
   */
  public void treeNodeStructureChanged(DefaultMutableTreeNode node) {
    ((DefaultTreeModel) jTree.getModel()).nodeStructureChanged(node);
  }

  /**
   * insertNodeInto
   *
   * @param newChild
   * @param parent
   * @param index
   */
  public void insertNodeInto(DefaultMutableTreeNode newChild, DefaultMutableTreeNode parent, int index) {
    DefaultTreeModel treeModel = (DefaultTreeModel)jTree.getModel();
    treeModel.insertNodeInto(newChild,parent,index);
  }
  
  /**
   * removeNode
   *
   * @param node
   */
  public void removeNode(DefaultMutableTreeNode node) {
    DefaultTreeModel treeModel = (DefaultTreeModel)jTree.getModel();
    treeModel.removeNodeFromParent(node);
  }

  /**
   * getSelectionPaths
   *
   * @return
   */
  public TreePath[] getSelectionPaths() {
    return jTree.getSelectionPaths();
  }

  /**
   * getLeadSelectionPath
   *
   * @return
   */
  public TreePath getLeadSelectionPath() {
    return jTree.getLeadSelectionPath();
  }

  /**
   * This method initializes jPopupMenu	
   * 	
   * @return javax.swing.JPopupMenu	
   */
  private JPopupMenu getJPopupMenu() {
    if (jPopupMenu == null) {
      jPopupMenu = new JPopupMenu();
      jPopupMenu.add(ActionManager.getCreateBasicElementAction());
      jPopupMenu.add(ActionManager.getCreateContainerAction());
      jPopupMenu.add(ActionManager.getExportContainerAction());
      jPopupMenu.addSeparator();
      jPopupMenu.add(ActionManager.getDeleteContainerElementAction());
    }
    return jPopupMenu;
  }

  /**
   * addTreeSelectionListener
   *
   * @param listener
   */
  public void addTreeSelectionListener(TreeSelectionListener listener) {
    getJTree().addTreeSelectionListener(listener);
  }
  
  /**
   * ElementTreeMouseListener
   */
  private final class ElementTreeMouseListener extends java.awt.event.MouseAdapter {
    public void mousePressed(java.awt.event.MouseEvent e) {
      if (e.isPopupTrigger()) {
        selectNodeForLocation(e.getPoint());
        getJPopupMenu().show(e.getComponent(), e.getX(), e.getY());
      }
    }

    public void mouseReleased(java.awt.event.MouseEvent e) {
      if (e.isPopupTrigger()) {
        selectNodeForLocation(e.getPoint());
        getJPopupMenu().show(e.getComponent(), e.getX(), e.getY());
      }
    }

    private void selectNodeForLocation(Point point) {
      TreePath path = jTree.getPathForLocation((int)point.getX(), (int)point.getY());
      if (path != null) {
        jTree.setSelectionPath(path);
      }
    }
  }
  
}
